/* SPDX-License-Identifier: GPL-2.0 */
#include <config.h>
#include <linux/linkage.h>
#include <asm/encoding.h>

#ifdef CONFIG_32BIT
#define LREG            lw
#define SREG            sw
#define REGBYTES        4
#define RELOC_TYPE      R_RISCV_32
#define SYM_INDEX       0x8
#define SYM_SIZE        0x10
#else
#define LREG            ld
#define SREG            sd
#define REGBYTES        8
#define RELOC_TYPE      R_RISCV_64
#define SYM_INDEX       0x20
#define SYM_SIZE        0x18
#endif
.extern boot_params_stash

.global save_boot_params
save_boot_params:
	la  t0, boot_params_stash
	SREG    a0, REGBYTES * 0(t0)
	SREG    a1, REGBYTES * 1(t0)
	SREG    a2, REGBYTES * 2(t0)
	SREG    a3, REGBYTES * 3(t0)
	SREG    a4, REGBYTES * 4(t0)
	SREG    a5, REGBYTES * 5(t0)
	SREG    a6, REGBYTES * 6(t0)
	SREG    a7, REGBYTES * 7(t0)
	SREG    s0, REGBYTES * 8(t0)
	SREG    s1, REGBYTES * 9(t0)
	SREG    s2, REGBYTES * 10(t0)
	SREG    s3, REGBYTES * 11(t0)
	SREG    s4, REGBYTES * 12(t0)
	SREG    s5, REGBYTES * 13(t0)
	SREG    s6, REGBYTES * 14(t0)
	SREG    s7, REGBYTES * 15(t0)
	SREG    s8, REGBYTES * 16(t0)
	SREG    s9, REGBYTES * 17(t0)
	SREG    s10, REGBYTES * 18(t0)
	SREG    s11, REGBYTES * 19(t0)
	SREG    sp, REGBYTES * 20(t0)
	SREG    ra, REGBYTES * 21(t0)
	j save_boot_params_ret


.global save_context_form_bootrom
save_context_form_bootrom:
	addi    sp, sp, -32 * REGBYTES
	SREG    x1,   1 * REGBYTES(sp)
	SREG    x2,   2 * REGBYTES(sp)
	SREG    x3,   3 * REGBYTES(sp)
	SREG    x4,   4 * REGBYTES(sp)
	SREG    x5,   5 * REGBYTES(sp)
	SREG    x6,   6 * REGBYTES(sp)
	SREG    x7,   7 * REGBYTES(sp)
	SREG    x8,   8 * REGBYTES(sp)
	SREG    x9,   9 * REGBYTES(sp)
	SREG    x10, 10 * REGBYTES(sp)
	SREG    x11, 11 * REGBYTES(sp)
	SREG    x12, 12 * REGBYTES(sp)
	SREG    x13, 13 * REGBYTES(sp)
	SREG    x14, 14 * REGBYTES(sp)
	SREG    x15, 15 * REGBYTES(sp)
	SREG    x16, 16 * REGBYTES(sp)
	SREG    x17, 17 * REGBYTES(sp)
	SREG    x18, 18 * REGBYTES(sp)
	SREG    x19, 19 * REGBYTES(sp)
	SREG    x20, 20 * REGBYTES(sp)
	SREG    x21, 21 * REGBYTES(sp)
	SREG    x22, 22 * REGBYTES(sp)
	SREG    x23, 23 * REGBYTES(sp)
	SREG    x24, 24 * REGBYTES(sp)
	SREG    x25, 25 * REGBYTES(sp)
	SREG    x26, 26 * REGBYTES(sp)
	SREG    x27, 27 * REGBYTES(sp)
	SREG    x28, 28 * REGBYTES(sp)
	SREG    x29, 29 * REGBYTES(sp)
	SREG    x30, 30 * REGBYTES(sp)
	SREG    x31, 31 * REGBYTES(sp)
	csrr    t3, MODE_PREFIX(tvec)
	SREG    t3, 32 * REGBYTES(sp)
	mv t4, sp
	la  t0, sp_reg
	SREG t4, REGBYTES * 0(t0)
	j save_boot_params

.global restore_context_to_bootrom
restore_context_to_bootrom:
	la      t0, sp_reg
	LREG    sp, REGBYTES * 0(t0)
	LREG    a0, 32 * REGBYTES(sp)
	csrw    MODE_PREFIX(tvec), a0
	LREG    x1,   1 * REGBYTES(sp)
	LREG    x3,   3 * REGBYTES(sp)
	LREG    x4,   4 * REGBYTES(sp)
	LREG    x5,   5 * REGBYTES(sp)
	LREG    x6,   6 * REGBYTES(sp)
	LREG    x7,   7 * REGBYTES(sp)
	LREG    x8,   8 * REGBYTES(sp)
	LREG    x9,   9 * REGBYTES(sp)
	LREG    x10, 10 * REGBYTES(sp)
	LREG    x11, 11 * REGBYTES(sp)
	LREG    x12, 12 * REGBYTES(sp)
	LREG    x13, 13 * REGBYTES(sp)
	LREG    x14, 14 * REGBYTES(sp)
	LREG    x15, 15 * REGBYTES(sp)
	LREG    x16, 16 * REGBYTES(sp)
	LREG    x17, 17 * REGBYTES(sp)
	LREG    x18, 18 * REGBYTES(sp)
	LREG    x19, 19 * REGBYTES(sp)
	LREG    x20, 20 * REGBYTES(sp)
	LREG    x21, 21 * REGBYTES(sp)
	LREG    x22, 22 * REGBYTES(sp)
	LREG    x23, 23 * REGBYTES(sp)
	LREG    x24, 24 * REGBYTES(sp)
	LREG    x25, 25 * REGBYTES(sp)
	LREG    x26, 26 * REGBYTES(sp)
	LREG    x27, 27 * REGBYTES(sp)
	LREG    x28, 28 * REGBYTES(sp)
	LREG    x29, 29 * REGBYTES(sp)
	LREG    x30, 30 * REGBYTES(sp)
	LREG    x31, 31 * REGBYTES(sp)
	addi    sp, sp, 32 * REGBYTES
	ret


.global board_return_to_bootrom
board_return_to_bootrom:
	j restore_context_to_bootrom
